﻿using _8280WEBSocket.Command;
using AutoUpdaterDotNET;
using DoNetDrive.Common.Extensions;
using DoNetDrive.Core;
using DoNetDrive.Core.Command;
using DoNetDrive.Core.Command.Text;
using DoNetDrive.Core.Connector;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace _8280WEBSocket
{
    public partial class MainForm : Form, INMain
    {

        ConnectorAllocator Allocator;
        TCPIOObserverHandler obServer;
        Encoding UTF8 = Encoding.UTF8;
        public MainForm()
        {
            InitializeComponent();
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            AutoUpdater.CheckForUpdateEvent += AutoUpdater_CheckForUpdateEvent;
            AutoUpdater.Start("https://fcosstest.oss-cn-zhangjiakou.aliyuncs.com/8280%E8%B0%83%E8%AF%95%E5%99%A8/update.xml");
      

            Allocator = ConnectorAllocator.GetAllocator();
            Allocator.CommandCompleteEvent += Allocator_CommandCompleteEvent;
            Allocator.ConnectorClosedEvent += Allocator_ConnectorClosedEvent;
            Allocator.ConnectorConnectedEvent += Allocator_ConnectorConnectedEvent;
            Allocator.ConnectorErrorEvent += Allocator_ConnectorErrorEvent;
            Allocator.TransactionMessage += Allocator_TransactionMessage;
            obServer = new TCPIOObserverHandler();
            obServer.DisposeRequestEvent += ObServer_DisposeRequestEvent;
            obServer.DisposeResponseEvent += ObServer_DisposeResponseEvent;
            LoadLocalHost();

            cmbConnType.SelectedIndex = 0;
            cmbLanguage.SelectedIndex = 0;
        }

        private void AutoUpdater_CheckForUpdateEvent(UpdateInfoEventArgs args)
        {

            if (args.Error == null)
            {
                if (args.IsUpdateAvailable)//需要更新
                {
                    try
                    {
                        if (AutoUpdater.DownloadUpdate(args))
                        {
                            Application.Exit();
                            return;
                        }
                    }
                    catch (Exception exception)
                    {//更新下载失败

                    }

                }
            }

            Invoke(new Action(IniForm));
        }

        private void IniForm()
        {

        }

        private void Allocator_TransactionMessage(INConnectorDetail connector, DoNetDrive.Core.Data.INData EventData)
        {
            AddLog("监控");
        }

        /// <summary>
        /// 处理请求
        /// </summary>
        /// <param name="connector"></param>
        /// <param name="len"></param>
        /// <param name="message"></param>
        private void ObServer_DisposeResponseEvent(DoNetDrive.Core.Connector.INConnector connector, int len, string message)
        {

        }
        /// <summary>
        /// 处理响应
        /// </summary>
        /// <param name="connector"></param>
        /// <param name="len"></param>
        /// <param name="message"></param>
        private void ObServer_DisposeRequestEvent(DoNetDrive.Core.Connector.INConnector connector, int len, string message)
        {
            AddLog(message);
        }
        /// <summary>
        /// 连接错误
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="connector"></param>
        private void Allocator_ConnectorErrorEvent(object sender, DoNetDrive.Core.Connector.INConnectorDetail connector)
        {
            AddLog("连接错误");
        }
        /// <summary>
        /// 连接成功
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="connector"></param>
        private void Allocator_ConnectorConnectedEvent(object sender, DoNetDrive.Core.Connector.INConnectorDetail connector)
        {
            var conn = Allocator.GetConnector(connector);
            conn.AddRequestHandle(obServer);
            conn.OpenForciblyConnect();
            AddLog("连接成功");
        }
        /// <summary>
        /// 连接关闭
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="connector"></param>
        private void Allocator_ConnectorClosedEvent(object sender, DoNetDrive.Core.Connector.INConnectorDetail connector)
        {
            AddLog("连接关闭");
        }
        /// <summary>
        /// 命令成功
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Allocator_CommandCompleteEvent(object sender, DoNetDrive.Core.Command.CommandEventArgs e)
        {

        }
        private void LoadLocalHost()
        {
            cmbLocalIP.Items.Clear();

            IPHostEntry localentry = Dns.GetHostEntry(Dns.GetHostName());
            foreach (IPAddress oItem in localentry.AddressList)
            {
                IPAddress ip = oItem;

                if (ip.IsIPv4MappedToIPv6)
                {
                    ip = ip.MapToIPv4();
                }
                if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                {
                    cmbLocalIP.Items.Add(ip.ToString());
                }
            }

            if (cmbLocalIP.Items.Count > 0)
            {
                cmbLocalIP.SelectedIndex = cmbLocalIP.Items.Count - 1;
            }
        }
        private void BtnConnectionService_Click(object sender, EventArgs e)
        {
            Allocator.OpenConnector(GetConnectorDetail());
        }

        private void BtnTest_Click(object sender, EventArgs e)
        {
            var client = GetConnectorDetail();
            var detail = new TextCommandDetail(client);
            var par = new TextCommandParameter("测试", UTF8);
            var cmd = new TextCommand(detail, par);
            Allocator.AddCommand(cmd);
        }

        private void BtnWorkParam_Click(object sender, EventArgs e)
        {
            WorkParamForm form = new WorkParamForm(this);
            form.Show();
            if (form.WindowState == FormWindowState.Minimized)
                form.WindowState = FormWindowState.Normal;
            form.Activate();
            ShowFrm(form);
        }
        /// <summary>
        /// 显示窗口在侧边栏
        /// </summary>
        /// <param name="chi"></param>
        private void ShowFrm(Form chi)
        {
            Screen scr = Screen.PrimaryScreen;

            foreach (Screen ss in Screen.AllScreens)
            {
                var rc = ss.Bounds;
                if (rc.Left < this.Left && (rc.Left + rc.Width) > this.Left)
                {
                    if (rc.Top < this.Top && (rc.Top + rc.Bottom) > this.Top)
                    {
                        scr = ss;
                        break;
                    }
                }

            }

            var scrRc = scr.Bounds;
            int iLeft = (scrRc.Width - (Width + chi.Width)) / 2;
            int iTop = (scrRc.Height - (Height > chi.Height ? Height : chi.Height)) / 2;

            this.Left = scrRc.Left + iLeft;
            this.Top = scrRc.Top + iTop;

            chi.Left = scrRc.Left + iLeft + this.Width;
            chi.Top = scrRc.Top + iTop;
            if (this.Left < 0) this.Left = 0;
            if ((chi.Left + chi.Width) > scrRc.Width)
            {
                chi.Left = scrRc.Width - chi.Width;
            }

        }
        public void AddLog(string s)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new Action(() =>
                {
                    AddLog(s);
                }));
            }
            else
            {
                int index = GV_Log.Rows.Add();
                GV_Log.Rows[index].Cells[0].Value = DateTime.Now;
                GV_Log.Rows[index].Cells[1].Value = s;
            }
        }

        public void AddLog(StringBuilder s)
        {
            AddLog(s.ToString());
        }

        public INConnectorDetail GetConnectorDetail()
        {
            var sRemoteIP = Txt_RemoteIP.Text;
            var sLocalIP = cmbLocalIP.Text;
            var iRemotePort = int.Parse(Txt_RemotePort.Text);
            var iLocalPort = int.Parse(TxtLocalPort.Text);
            var webSocketClient = new DoNetDrive.Core.Connector.WebSocket.Client.WebSocketClientDetail(sRemoteIP, iRemotePort, "", 0)
            {
                Path = "/WebSocket"
            };
            return webSocketClient;
        }

        public void AddCommand(INCommand cmd)
        {
            if (cmd != null)
            {
                Allocator.AddCommand(cmd);
            }
            else
            {
                MessageBox.Show("INCommand is null");
            }
        }

        public INCommandDetail GetCommandDetail()
        {
            var connDtl = GetConnectorDetail();
            var cmdDtl = new TextCommandDetail(connDtl);
            cmdDtl.Timeout = 3000;
            return cmdDtl;

        }

        private void btnPersonForm_Click(object sender, EventArgs e)
        {
            PersonForm form = new PersonForm(this);
            form.Show();
            if (form.WindowState == FormWindowState.Minimized)
                form.WindowState = FormWindowState.Normal;
            form.Activate();
            ShowFrm(form);
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            GV_Log.Rows.Clear();
        }
    }
}
